package Cn.edu.zafu.bigdata.x.cxy;

import java.io.*;
import java.net.*;
import java.util.concurrent.CopyOnWriteArrayList;

public class TCPServer {
    private ServerSocket serverSocket;
    private CopyOnWriteArrayList<PrintWriter> clients = new CopyOnWriteArrayList<>();

    public TCPServer(int port) {
        try {
            serverSocket = new ServerSocket(port);
            System.out.println("服务器正在监听 " + port + "端口");
        } catch (IOException e) {
            System.err.println("服务器无法监听 " + port + "端口");
            e.printStackTrace();
            System.exit(1);
        }
    }

    public void start() {
        try {
            while (true) {
                Socket socket = serverSocket.accept();
                System.out.println("新客户端已连接");
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                clients.add(out);

                new Thread(new ClientHandler(socket, clients)).start();
            }
        } catch (IOException e) {
            System.err.println("连接请求失败");
            e.printStackTrace();
        }
    }

    private static class ClientHandler implements Runnable {
        private Socket socket;
        private CopyOnWriteArrayList<PrintWriter> clients;

        public ClientHandler(Socket socket, CopyOnWriteArrayList<PrintWriter> clients) {
            this.socket = socket;
            this.clients = clients;
        }

        @Override
        public void run() {
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String nickname = in.readLine();
                System.out.println("用户: " + nickname);

                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    for (PrintWriter out : clients) {
                        out.println(nickname + ": " + inputLine);
                    }
                }
            } catch (IOException e) {
                System.err.println("Error in client handler.");
                e.printStackTrace();
            } finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    System.err.println("Error closing socket.");
                    e.printStackTrace();
                }
                clients.removeIf(out -> out.checkError());
            }
        }
    }

    public static void main(String[] args) {
        TCPServer server = new TCPServer(5678);
        server.start();
    }
}